package com.spzx.payment.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.alipay.api.response.AlipayTradeWapPayResponse;
import com.spzx.common.core.constant.SecurityConstants;
import com.spzx.common.core.domain.R;
import com.spzx.common.rabbit.constant.MqConst;
import com.spzx.common.rabbit.service.RabbitService;
import com.spzx.order.api.RemoteOrderService;
import com.spzx.order.api.domain.OrderInfo;
import com.spzx.payment.config.AlipayConfig;
import com.spzx.payment.domain.PaymentInfo;
import com.spzx.payment.service.IAlipayService;
import com.spzx.payment.service.IPaymentInfoService;
import jakarta.servlet.http.HttpServletRequest;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Map;

/**
 * Description:
 *
 * @author Yanxinhao on 2024/12/30
 */

@Service
@Slf4j
public class AlipayServiceImpl implements IAlipayService {
    @Autowired
    private AlipayClient alipayClient;
    @Autowired
    private IPaymentInfoService paymentInfoService;
    @Autowired
    private RemoteOrderService orderService;
    @Autowired
    private RabbitService rabbitService;

    /**
     * 支付宝下单
     * @param orderNo 订单编号
     * @return 支付宝sdk返回的表单
     */
    @Override
    @SneakyThrows
    public String submitAlipay(String orderNo) {
        //1.先通过订单号去获取PaymentInfo，并且保存当前的订单信息
        PaymentInfo paymentInfo = paymentInfoService.savePaymentInfo(orderNo);

        //2. 创建请求对象
        AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();//创建API对应的request
        // 设置同步回调
        alipayRequest.setReturnUrl(AlipayConfig.return_payment_url);
        // 设置异步回调
        alipayRequest.setNotifyUrl(AlipayConfig.notify_payment_url);

        /******必传参数******/
        JSONObject bizContent = new JSONObject();
        //商户订单号，商家自定义，保持唯一性
        bizContent.put("out_trade_no", paymentInfo.getOrderNo());
        //支付金额，最小值0.01元
        bizContent.put("total_amount", paymentInfo.getAmount());
        //bizContent.put("total_amount", 0.01);

        //订单标题，不可使用特殊符号
        bizContent.put("subject", paymentInfo.getContent());
        /******可选参数******/
        //手机网站支付默认传值QUICK_WAP_WAY
        bizContent.put("product_code", "QUICK_WAP_WAY");

        alipayRequest.setBizContent(bizContent.toString());
        AlipayTradeWapPayResponse response = alipayClient.pageExecute(alipayRequest,"POST");

        return response.getBody(); //调用SDK生成表单;
    }

    /**
     * 用户使用支付宝支付完毕后，支付宝会携带支付结果访问这个接口方法
     * 即支付宝的回调函数
     * 返回的类型必须是”success“才是成功
     * 其他的均是失败
     * @param paramMap
     * @param request
     * @return
     */
    @Override
    public String getNotify(Map<String, String> paramMap, HttpServletRequest request) {
        log.info("支付宝支付回调参数：{}", paramMap);
        String result = "failure";

        try {
            //调用SDK验证签名
            boolean signVerified = AlipaySignature.rsaCheckV1(
                    paramMap,
                    AlipayConfig.alipay_public_key,
                    AlipayConfig.charset,
                    AlipayConfig.sign_type
            );

            //校验验签是否成功
            String outTradeNo = paramMap.get("out_trade_no");
            if(!signVerified){
                log.error("订单 {} 验签失败", outTradeNo);
                return result;
            }
            log.error("验签成功！");

            //商家需要验证该通知数据中的 out_trade_no 是否为商家系统中创建的订单号。
            R<OrderInfo> orderInfoResult = orderService.getByOrderNo(outTradeNo, SecurityConstants.INNER);
            if(R.FAIL == orderInfoResult.getCode()){
                log.error("远程获取订单 {} 失败", outTradeNo);
                return result;
            }
            if(orderInfoResult.getData() == null){
                log.error("订单 {} 不存在", outTradeNo);
                return result;
            }
            OrderInfo orderInfo = orderInfoResult.getData();

            // 判断 total_amount 是否确实为该订单的实际金额（即商户订单创建时的金额）。
            String totalAmount = paramMap.get("total_amount");
            if(orderInfo.getTotalAmount().compareTo(new BigDecimal(totalAmount)) != 0){
                log.error("订单 {} 金额不一致", outTradeNo);
                return result;
            }

            // 校验通知中的 seller_id（或者 seller_email) 是否为 out_trade_no 这笔单据的对应的操作方（有的时候，一个商家可能有多个 seller_id/seller_email）。
            // "2088721053967723" 沙箱中的 商户PID
            String sellerId = paramMap.get("seller_id");
            if(!"2088721053967723".equals(sellerId)){
                log.error("订单 {} 商家不一致", outTradeNo);
                return result;
            }

            //验证 app_id 是否为该商家本身。
            String appId = paramMap.get("app_id");
            if(!AlipayConfig.app_id.equals(appId)){
                log.error("订单 {} appid不一致", outTradeNo);
                return result;
            }

            // 交易状态
            String tradeStatus = paramMap.get("trade_status");
            if ("TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus)) {
                // 正常的支付成功，我们应该更新交易记录状态
                paymentInfoService.updatePaymentStatus(paramMap, 2);

                //基于MQ通知订单系统，修改订单状态
                rabbitService.sendMessage(MqConst.EXCHANGE_PAYMENT_PAY, MqConst.ROUTING_PAYMENT_PAY, outTradeNo);
                //基于MQ通知商品系统，扣减库存
                rabbitService.sendMessage(MqConst.EXCHANGE_PRODUCT, MqConst.ROUTING_MINUS, outTradeNo);
                return "success";
            }
        } catch (AlipayApiException e){
            e.printStackTrace();
        }


        return result;
    }
}